package services

import (
	"database/sql"
	"dict-server/config"
	"dict-server/dao"
	models "dict-server/dao/model"
	"fmt"
	"log"
	"time"

	"github.com/go-sql-driver/mysql"
)

var wordDAO *dao.WordDAO // 单词DAO实例
var db *sql.DB           // 数据库连接实例

// InitDB 初始化数据库连接及表结构
func InitDB(cfg *config.DatabaseConfig) error {
	// 临时连接MySQL服务器-用于创建数据库
	tempDB, err := connectWithoutDB(cfg)
	if err != nil {
		return fmt.Errorf("临时连接失败: %w", err)
	}
	defer tempDB.Close()

	// 创建目标数据库-若不存在
	if err := createDatabase(tempDB, cfg.Name); err != nil {
		return fmt.Errorf("创建数据库失败: %w", err)
	}

	// 连接到目标数据库
	if err := connectWithDB(cfg); err != nil {
		return fmt.Errorf("连接数据库失败: %w", err)
	}

	// 配置连接池参数
	setupConnPool(cfg)

	// 验证数据库连接
	if err := db.Ping(); err != nil {
		return fmt.Errorf("连接验证失败: %w", err)
	}

	// 创建单词表-若不存在
	if err := createWordsTable(); err != nil {
		return fmt.Errorf("创建表结构失败: %w", err)
	}

	// 初始化DAO层
	wordDAO = dao.NewWordDAO(db)

	log.Println("数据库初始化成功")
	return nil
}

// 临时连接-不指定数据库
func connectWithoutDB(cfg *config.DatabaseConfig) (*sql.DB, error) {
	mysqlCfg := mysql.Config{
		User:                 cfg.User,
		Passwd:               cfg.Password,
		Net:                  "tcp",
		Addr:                 fmt.Sprintf("%s:%d", cfg.Host, cfg.Port),
		ParseTime:            true,
		Loc:                  time.Local,
		AllowNativePasswords: true,
	}
	return sql.Open("mysql", mysqlCfg.FormatDSN())
}

// 连接到指定数据库
func connectWithDB(cfg *config.DatabaseConfig) error {

	mysqlCfg := mysql.Config{
		User:                 cfg.User,
		Passwd:               cfg.Password,
		Net:                  "tcp",
		Addr:                 fmt.Sprintf("%s:%d", cfg.Host, cfg.Port),
		DBName:               cfg.Name,
		ParseTime:            true,
		Loc:                  time.Local,
		AllowNativePasswords: true,
	}

	var err error
	db, err = sql.Open("mysql", mysqlCfg.FormatDSN())
	return err
}

// 创建数据库-若不存在
func createDatabase(db *sql.DB, dbName string) error {
	_, err := db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", dbName))
	return err
}

// 配置连接池
func setupConnPool(cfg *config.DatabaseConfig) {
	db.SetMaxOpenConns(cfg.MaxOpenConns)
	db.SetMaxIdleConns(cfg.MaxIdleConns)
	db.SetConnMaxLifetime(cfg.ConnMaxLifetime)
}

// 创建单词表结构
func createWordsTable() error {
	query := `
	CREATE TABLE IF NOT EXISTS words (
		word VARCHAR(100) NOT NULL PRIMARY KEY,
		trans TEXT NOT NULL
	) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
	`
	_, err := db.Exec(query)
	return err
}

// 以下为服务层对外提供的接口，内部调用DAO层实现

// GetWord 查询单词详情
func GetWord(word string) (*models.Word, error) {
	return wordDAO.GetWord(word)
}

// InsertWords 批量插入单词
func InsertWords(words []models.Word, batchSize int) (int, error) {
	return wordDAO.InsertWords(words, batchSize)
}

// CleanWords 清空单词表数据
func CleanWords() (int64, error) {
	return wordDAO.CleanWords()
}

// CloseDB 关闭数据库连接
func CloseDB() error {
	if db != nil {
		return db.Close()
	}
	return nil
}
